package com.xg.util.excel;

import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.handler.SheetWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.xg.model.entity.OneData;
import com.xg.model.entity.Styleable;
import com.xg.model.entity.TwoData;
import org.apache.poi.ss.usermodel.*;

import java.util.List;
import java.util.Map;
import java.util.function.Function;

/**
 * Excel 样式处理器，负责：
 * - 冻结窗格设置
 * - 单元格样式动态应用（如新增、修改、删除行）
 */
public class ExcelTemplateStyleHandler<T> implements SheetWriteHandler, CellWriteHandler {

    private final Map<Class<?>, List<?>> dataMap;

    public ExcelTemplateStyleHandler(Map<Class<?>, List<?>> dataMap) {
        this.dataMap = dataMap;
    }

    @Override
    public void afterSheetCreate(com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder writeWorkbookHolder,
                                 WriteSheetHolder writeSheetHolder) {
        Sheet sheet = writeSheetHolder.getSheet();
        String sheetName = sheet.getSheetName();

        if ("第一页".equals(sheetName)) {
            sheet.createFreezePane(0, 2); // 第一页冻结前两行
        } else if ("第二页".equals(sheetName)) {
            sheet.createFreezePane(0, 1); // 第二页冻结第一行
        }
    }

    @Override
    public void afterCellDispose(
            WriteSheetHolder writeSheetHolder,
            WriteTableHolder writeTableHolder,
            List<WriteCellData<?>> cellDataList,
            Cell cell,
            Head head,
            Integer relativeRowIndex,
            Boolean isHead
    ) {
        int rowIndex = cell.getRowIndex();

        for (Map.Entry<Class<?>, List<?>> entry : dataMap.entrySet()) {
            Class<?> clazz = entry.getKey();
            List<?> dataList = entry.getValue();

            for (Object obj : dataList) {
                if (clazz.isAssignableFrom(obj.getClass())) {
                    if (obj instanceof Styleable) {
                        Styleable item = (Styleable) obj;
                        if (item instanceof OneData) {
                            handleOneDataRow((OneData) item, rowIndex, cell, cellDataList);
                        } else if (item instanceof TwoData) {
                            handleTwoDataRow((TwoData) item, rowIndex, cell, cellDataList);
                        }
                    }
                }
            }
        }
    }

    private void handleOneDataRow(OneData data, int rowIndex, Cell cell, List<WriteCellData<?>> cellDataList) {
        try {
            if (data.getNum() != null && rowIndex == data.getNum() + 1) { // 调整为 rowIndex == data.getNum() + 3
                applyStyles(data, cell.getColumnIndex(), cellDataList, field -> ReflectionTemplateUtils.getColumnIndexByField(OneData.class, field));
            }
        } catch (Exception e) {
            System.err.println("处理 OneData 样式时发生异常：" + e.getClass().getSimpleName() + ": " + e.toString());
        }
    }

    private void handleTwoDataRow(TwoData data, int rowIndex, Cell cell, List<WriteCellData<?>> cellDataList) {
        try {
            if (data.getNum() != null && rowIndex == data.getNum() - 1) { // 调整为 rowIndex == data.getNum() + 2
                applyStyles(data, cell.getColumnIndex(), cellDataList, field -> ReflectionTemplateUtils.getColumnIndexByField(TwoData.class, field));
            }
        } catch (Exception e) {
            System.err.println("处理 TwoData 样式时发生异常：" + e.getMessage());
        }
    }

    private <T> void applyStyles(T data, int colIndex, List<WriteCellData<?>> cellDataList,
                                 Function<String, Integer> fieldMapper) {
        if (!(data instanceof Styleable)) {
            setDefaultStyle(cellDataList);
            return;
        }

        Styleable styleable = (Styleable) data;
        String operationType = styleable.getOperationType();
        String modifiedField = styleable.getModifiedField();

        if (operationType == null || operationType.isEmpty()) {
            setDefaultStyle(cellDataList);
            return;
        }

        WriteCellStyle style = new WriteCellStyle();
        style.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
        style.setBorderLeft(BorderStyle.THIN);
        style.setBorderRight(BorderStyle.THIN);
        style.setBorderTop(BorderStyle.THIN);
        style.setBorderBottom(BorderStyle.THIN);

        if ("update".equals(operationType) && modifiedField != null && !modifiedField.isEmpty()) {
            // 解析 modifiedField，拆分为单独的字段名
            for (String field : modifiedField.split(",")) {
                Integer targetCol = fieldMapper.apply(field.trim()); // 注意这里添加了 trim() 来去除可能的空格
                if (targetCol != null && targetCol.equals(colIndex)) {
                    StyleTemplateStrategyFactory.getStrategy(operationType, colIndex, targetCol).applyStyle(style);
                    break;
                }
            }
        } else {
            StyleTemplateStrategyFactory.getStrategy(operationType, -1, -1).applyStyle(style);
        }

        for (WriteCellData<?> cellData : cellDataList) {
            cellData.setWriteCellStyle(style);
        }
    }

    private void setDefaultStyle(List<WriteCellData<?>> cellDataList) {
        WriteCellStyle defaultStyle = new WriteCellStyle();
        defaultStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
        defaultStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());

        for (WriteCellData<?> cellData : cellDataList) {
            cellData.setWriteCellStyle(defaultStyle);
        }
    }

}
